package com.casa.POI.dianping;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;


public class CleanupExecutor extends Executor {
	
	@Override
	public void execute() {
		super.execute();
		List<String> urls = getBadShopUrls();
		if (urls.size() != 0) {
			Console.writeLine("process %d bad shops", urls.size());
			List<Integer> citiesToProcess = setCityStatus(urls);
			new Spider(citiesToProcess.toArray(new Integer[0])).run();
		}
	}

	private List<Integer> setCityStatus(List<String> urls) {
		List<Integer> citiesToProcess = new ArrayList<Integer>();
		Session s = SessionManager.getInstance().openSession();
		s.beginTransaction();
		for (String url : urls) {
			ShopUrl shopUrl = cleanFetched(s, url);
			int cityId = shopUrl.getCityId();
			if (!citiesToProcess.contains(cityId))
				citiesToProcess.add(cityId);
			deleteBadItems(s, url);
			stepBackward(s, shopUrl);
		}
		s.getTransaction().commit();
		s.close();
		return citiesToProcess;
	}

	public ShopUrl cleanFetched(Session s, String url) {
		ShopUrl shopUrl = (ShopUrl) s.get(ShopUrl.class, url);
		shopUrl.setFetched(0);
		s.update(shopUrl);
		return shopUrl;
	}

	public void stepBackward(Session s, ShopUrl shopUrl) {
		Status status = (Status) s.get(Status.class, shopUrl.getCityId());
		status.setStep(3);
		s.update(status);
	}

	private void deleteBadItems(Session s, String url) {
		Query deleteShopData = s.createQuery("delete ShopData where url = ?");
		deleteShopData.setString(0, url);
		deleteShopData.executeUpdate();
		Query deleteShop = s.createQuery("delete Shop where url = ?");
		deleteShop.setString(0, url);
		deleteShop.executeUpdate();
	}

	@SuppressWarnings("unchecked")
	private List<String> getBadShopUrls() {
		Session s = SessionManager.getInstance().openSession();
		Criteria c = s.createCriteria(Shop.class);
		c.setProjection(Projections.property("url"));
		c.add(Property.forName("cityId").isNull());
		List<String> urls = c.list();
		s.close();
		return urls;
	}
}
